package com.atwisdom.star.core.bsl.modelClass.hier.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.actionType.modelClass.hier.HierActionType;
import com.atwisdom.star.common.util.ExpressionUtil;
import com.atwisdom.star.common.util.JsonUtil;
import com.atwisdom.star.common.util.UuidTool;
import com.atwisdom.star.common.vo.*;
import com.atwisdom.star.core.bsl.aop.HierInstanceAnnotation;
import com.atwisdom.star.core.bsl.functionClass.CalculateService;
import com.atwisdom.star.core.bsl.modelClass.hier.HierInstanceBslService;
import com.atwisdom.star.core.dao.pojo.modelClass.hier.HierInstance;
import com.atwisdom.star.core.dao.pojo.modelClass.staticLogic.StaticLogicInstance;
import com.atwisdom.star.core.dsl.modelClass.consume.ConsumeInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.hier.HierInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.hier.HierModelDslService;
import com.atwisdom.star.core.dsl.modelClass.logic.LogicInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.resource.ResourceInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.staticLogic.Impl.StaticLogicInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.tank.TankInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.twins.TwinsInstanceDslService;
import com.atwisdom.star.exception.pojo.BusinessException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.googlecode.aviator.AviatorEvaluator;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@AllArgsConstructor
@Service
@Slf4j
public class HierInstanceBslServiceImpl implements HierInstanceBslService, CalculateService {

    private HierModelDslService hierModelDslService;
    private HierInstanceDslService hierInstanceDslService;
    private LogicInstanceDslService logicInstanceDslService;
    private StaticLogicInstanceDslServiceImpl staticLogicInstanceDslService;
    private TwinsInstanceDslService twinsInstanceDslService;
    private TankInstanceDslService tankInstanceDslService;
    private ConsumeInstanceDslService consumeInstanceDslService;
    private ResourceInstanceDslService resourceInstanceDslService;

    /**
     * 服务工厂方法
     * @param actionDataList 参数
     * @return 参数
     * @throws BusinessException 异常
     */
    @Transactional
    public ResultInfo<?> responseFactory(List<ActionData<JSONObject>> actionDataList) throws BusinessException {
        ResultInfo<?> resultInfo = null;
        for (ActionData<JSONObject> actionData : actionDataList) {
            String action = actionData.getAction();
            HierActionType actionType = HierActionType.valueOf(action);
            String methodName = actionType.getMethodName();
            resultInfo = this.execMethod(methodName, actionData);
        }
        return resultInfo;
    }

    /**
     * 反射执行业务单元方法
     *
     * @param methodName 方法名
     * @param actionData 方法参数
     * @return 返回结果
     * @throws BusinessException 业务异常
     */
    public ResultInfo<?> execMethod(String methodName, ActionData<JSONObject> actionData) throws BusinessException {
        Class<? extends HierInstanceBslServiceImpl> clz = this.getClass();
        try {
            Method method = clz.getMethod(methodName, ActionData.class);
            HierInstanceBslServiceImpl service = (HierInstanceBslServiceImpl) AopContext.currentProxy();
            return (ResultInfo<?>) method.invoke(service, actionData);
        } catch (NoSuchMethodException ex) {
            throw new BusinessException("999999", "没有找到该方法(" + methodName + ")", ex);
        } catch (IllegalAccessException ex) {
            throw new BusinessException("999999", "没有访问该方法权限(" + methodName + ")", ex);
        } catch (InvocationTargetException ex) {
             Throwable targetException = ex.getTargetException();
            if (targetException instanceof BusinessException) {
                BusinessException bex = (BusinessException) targetException;
                throw new BusinessException("999999", bex.getErrorMsg(), ex);
            } else {
                throw new BusinessException("999999", "出错了请重试：(" + methodName + ")---" + ex.getMessage(), ex);
            }
        }
    }

    /**
     *
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> queryById(ActionData<JSONObject> actionData) {
        JSONObject resultJson = hierInstanceDslService.queryById(actionData.getId());
        return JsonResult.success(resultJson);
    }

    @Override
    @Transactional
//    @HierInstanceAnnotation
    public ResultInfo<?> updateById(ActionData<JSONObject> actionData) {
        List<JSONObject> dataList = actionData.getData();
        JSONObject data = dataList.get(0);
        HierInstance hierInstance = BeanUtil.copyProperties(data, HierInstance.class);
        HierInstance result = this.updateInsById(hierInstance);
        return JsonResult.success(result);
    }

    /**
     * 将一条数据分成指定条数的数据
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> copyById(ActionData<JSONObject> actionData) {
        Integer copyCount = actionData.getCopyCount();
        Map<String, Object> updateFieldMap = actionData.getUpdateFieldMap();
        Long id = actionData.getId();
        JSONObject hierJson = hierInstanceDslService.queryById(id);
        hierJson.remove("id");
        JSONObject valueJson = hierJson.getJSONObject("values");
        updateFieldMap.forEach((fieldName, fieldValue) -> {
            valueJson.put(fieldName, fieldValue);
        });
        hierJson.put("values", valueJson);
        List<JSONObject> copyList = new ArrayList<>();
        for (Integer i = 0; i < copyCount; i++) {
            JSONObject newHierJson =  ObjectUtil.cloneByStream(hierJson);
            copyList.add(newHierJson);
        }
        hierInstanceDslService.addChild(copyList);
        return JsonResult.success();
    }

    /**
     * 批量更新
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> updateBatchById(ActionData<JSONObject> actionData) {
        List<HierInstance> resultList = new ArrayList<>();
        List<JSONObject> dataList = actionData.getData();
        for (JSONObject data : dataList) {
            HierInstance hierInstance = BeanUtil.copyProperties(data, HierInstance.class);
            HierInstance result = this.updateInsById(hierInstance);
            resultList.add(result);
        }
        return JsonResult.success(resultList);
    }

    @Override
    public ResultInfo<?> updateByIds(ActionData<JSONObject> actionData) {
        List<JSONObject> dataList = actionData.getData();
        JSONObject data = dataList.get(0);
        List<HierInstance> result = hierInstanceDslService.updateByIds(data);
        return JsonResult.success(result);
    }


    /**
     * 不校验model的情况下，添加hier
     * @param actionData
     * @return
     *
     */
    @Override
    public ResultInfo<?> saveHierWithoutModel(ActionData<JSONObject> actionData) {
        List<JSONObject> dataList = actionData.getData();
        List<HierInstance> resultList = dataList.stream().map(dataJson -> {
            if (!dataJson.containsKey("containerModel")) {
                dataJson.put("containerModel", ModelType.StaticLogic.getCode());
            }
            /*if (dataJson.getLong("id") != null) {
                HierInstance hierInstance = BeanUtil.copyProperties(dataJson, HierInstance.class);
                return this.updateInsById(hierInstance);
            } else {
                return this.addHierInsChild(dataJson);
            }*/
            //原更新不处理可查询数据
            return this.addHierInsChild(dataJson);
        }).collect(Collectors.toList());

        return JsonResult.success(hierInstanceDslService.convertToJson(resultList));
    }

    @HierInstanceAnnotation
    @Override
    public HierInstance updateInsById(HierInstance hierInstance){
        return hierInstanceDslService.updateById(hierInstance);
    }

    @HierInstanceAnnotation
    @Override
    public HierInstance addHierInsChild(JSONObject dataJson){
        return hierInstanceDslService.addChild(dataJson);
    }

    /**
     * 根据条件查询出以下数据，需要根据指定条件处理后，增加到Hier中，
     *  [{"values": {
     *                 "date": null,
     *                 "material_bcode": "10001",
     *                 "quantity": 90,
     *                 "bin_id": null,
     *                 "warehouse_code": null,
     *                 "material_pcode": "10001",
     *                 "material_id": 24,
     *                 "bin_code": null,
     *                 "material_name": "落片",
     *                 "operator": null,
     *                 "warehouse_id": 1302
     *             },
     *             "className": "stock"
     * }]
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> addChild(ActionData<JSONObject> actionData) {
        String className = actionData.getClassName();
        String model = actionData.getModel();
        Long containerId = actionData.getContainerId();
        String parentId = actionData.getParentId();
        List<JSONObject> dataList = actionData.getData();
        List<String> fieldMapList = actionData.getFieldMapList();
        for (JSONObject data : dataList) {
            JSONObject hierJson = buildHierJson(className, model, containerId, parentId, fieldMapList, data);
            hierInstanceDslService.addChild(hierJson);
        }
        return JsonResult.success();
    }


    /**
     * 只更新有限条数
     * @param actionData
     * [
     *  {material_bcode: a, quantity: 3},
     *  {material_bcode: b, quantity: 4},
     * ]
     * @return
     */
    @Override
    public ResultInfo<?> updateLimitCount(ActionData<JSONObject> actionData) {
        Long containerId = actionData.getContainerId();
        String parentId = actionData.getParentId();
        String uniqueKey = actionData.getUniqueKey();
        JSONObject values = actionData.getValues();
        String model = actionData.getModel();
        String className = actionData.getClassName();
        List<HierInstance> hierInstanceList = hierInstanceDslService.queryChildByContainerId(model, className, containerId, parentId, "");
        List<JSONObject> dataList = actionData.getData();
        dataList.forEach(dataJson -> {
            // 更新条数
            Integer limitCount = dataJson.getInteger("limitCount");
            // 过滤记录的key
            Object uniqueValue = dataJson.get(uniqueKey);
            // 待更新的数据
            List<HierInstance> filterOutList = hierInstanceList.stream().filter(hierInstance -> uniqueValue.equals(hierInstance.getValues().get(uniqueKey)))
                    .collect(Collectors.toList());
            if (limitCount > filterOutList.size()) {
                throw new BusinessException(StatusCode.ERROR_DATA_ERROR.getCode(), "["+uniqueValue+"]可更新数量不足");
            }
            for (Integer i = 0; i < limitCount; i++) {
                HierInstance hierInstance = filterOutList.get(i);
                values.forEach((k,v)->hierInstance.getValues().put(k, v));
                hierInstanceDslService.updateById(hierInstance);
            }
        });
        return JsonResult.success();
    }
    /**
     * 根据源数据与映射关系，构建新的对象
     * @param className
     * @param model
     * @param containerId
     * @param parentId
     * @param fieldMapList
     * @param sourceDataJson
     * @return
     */
    private JSONObject buildHierJson(String className, String model, Long containerId, String parentId, List<String> fieldMapList, JSONObject sourceDataJson) {
        JSONObject hierJson = new JSONObject();
        hierJson.put("type", "tree");
        hierJson.put("name", UuidTool.getUUID32());
        hierJson.put("className", className);
        hierJson.put("containerModel", model);
        hierJson.put("containerId", containerId);
        hierJson.put("parentId", parentId);
        hierJson.put("nodeId", UuidTool.getUUID32());
        hierJson.put("nodeType", "leaf");
        JSONObject targetValueJson = new JSONObject();
        hierJson.put("values", targetValueJson);
        JSONObject values = sourceDataJson.getJSONObject("values");
        // 字段映射关系，source:target
        fieldMapList.forEach(fieldMap->{
            String[] filedArray = fieldMap.split(":");
            String sourceKey = filedArray[0];
            String targetKey = filedArray[1];
            Object targetVaue = handleExpression(values, sourceKey);
            targetValueJson.put(targetKey, targetVaue);
        });
        return hierJson;
    }


    /**
     * 删除hier
     * @param actionData, ids为hierInstance Id
     * @return
     *
     */
    @HierInstanceAnnotation
    @Override
    public ResultInfo<?>  deleteHierByIdList(ActionData<JSONObject> actionData) {
        List<Long> idList = actionData.getIds();
        boolean b = hierInstanceDslService.deleteByIdList(idList);
        return JsonResult.success(b);
    }

    /**
     * 删除hier
     * @param actionData, ids为hierInstance Id
     * @return
     */
    @Override
    public ResultInfo<?>  deleteByParentId(ActionData<JSONObject> actionData) {
        Long containerId = actionData.getContainerId();
        String model = actionData.getModel();
        String parentId = actionData.getParentId();
        boolean b = hierInstanceDslService.deleteByParentId(model, containerId, parentId);
        return JsonResult.success(b);
    }

    /**
     * 分组查询
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<Map<Object, List<HierInstance>>> queryAndGroupBy(ActionData<JSONObject> actionData) {
        String model = actionData.getModel();
        Long containerId = actionData.getInstanceId();
        String parentNodeId = actionData.getParentId();
        String groupByKey = actionData.getGroupKey();
        Map<Object, List<HierInstance>> resultMap = hierInstanceDslService.fetchByParentNodeIdAndGroupBy(model, containerId, parentNodeId, groupByKey);
        return JsonResult.success(resultMap);
    }

    /**
     * 查询hier中link的信息
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> query(ActionData<JSONObject> actionData) {
        List<HierInstance> hierInstanceList = queryList(actionData);
        return JsonResult.success(hierInstanceList);
    }

    /**
     * 查询hier中link的信息
     * @param actionData
     * @return
     */
    @Override
    public List<JSONObject> queryJson(ActionData<JSONObject> actionData) {
        List<HierInstance> hierInstanceList = queryList(actionData);
        return convertToJsonList(hierInstanceList);
    }

    private  List<HierInstance> queryList(ActionData<JSONObject> actionData) {
        String condition = actionData.getCondition();
        String hierValueCondition = actionData.getHierValueCondition();
        if (StrUtil.isNotBlank(hierValueCondition)) {
            hierValueCondition = hierValueCondition.replace("'$", "insValues->'$");
            condition += " and " + hierValueCondition;
        }
        String model = actionData.getModel();
        String className = actionData.getClassName();
        Long containerId = actionData.getInstanceId();
        String parentId = StrUtil.isNotBlank(actionData.getParentId())? actionData.getParentId() : "root";
        List<HierInstance> hierInstanceList = hierInstanceDslService.queryChildByContainerId(model, className, containerId, parentId, condition);
        return hierInstanceList;
    }



    // /**
    //  * 按条件查询，并汇总数据
    //  *
    //  * @param actionData 参数
    //  * @return 返回值
    //  */
    // // @Override
    // public ResultInfo<?> queryAndCalculate(ActionData<JSONObject> actionData) {
    //     List<JSONObject> queryJsonList = queryJson(actionData);
    //     String statisticsExpression = actionData.getStatisticsExpression();
    //     HashMap<String, Object> calculateParamMap = new HashMap<>();
    //     Map<String, String> jsonPathMap = actionData.getStatisticsJsonPathMap();
    //     jsonPathMap.forEach((paramName, jsonPath) -> {
    //         Object result = JsonPath.read(queryJsonList, jsonPath);
    //         calculateParamMap.put(paramName, result);
    //     });
    //     Expression expression = AviatorEvaluator.compile(statisticsExpression, true);
    //     Object result = expression.execute(calculateParamMap);
    //     return JsonResult.success(result);
    // }


    public List<JSONObject> convertToJsonList(List<HierInstance> hierInstanceList) {
        return hierInstanceList.stream().map(d -> convertToJson(d)).collect(Collectors.toList());
    }

        public JSONObject convertToJson(HierInstance hierInstance){
        JSONObject JsonObject = new JSONObject();
        JsonObject.put("id", hierInstance.getId());
        JsonObject.put("containerModel", hierInstance.getContainerModel());
        JsonObject.put("containerId", hierInstance.getContainerId());
        JsonObject.put("values", hierInstance.getValues());
        JsonObject.put("parentId", hierInstance.getParentId());
        JsonObject.put("nodeId", hierInstance.getNodeId());
        JsonObject.put("nodeType", hierInstance.getNodeType());
        JsonObject.put("type", hierInstance.getType());
        JsonObject.put("name", hierInstance.getName());
        JsonObject.put("className", hierInstance.getClassName());
        JsonObject.put("createdBy", hierInstance.getCreatedBy());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (hierInstance.getCreateTime() != null) {
            JsonObject.put("createTime", hierInstance.getCreateTime().format(formatter));
        }
        JsonObject.put("updatedBy", hierInstance.getUpdatedBy());
        if (hierInstance.getUpdateTime() != null) {
            JsonObject.put("updateTime", hierInstance.getUpdateTime().format(formatter));
        }
        return JsonObject;
    }


    /**
     * 分页查询
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> queryByPage(ActionData<JSONObject> actionData) {
        int current = actionData.getPageNumber();
        int size = actionData.getPageSize();
        String condition = actionData.getCondition();
        String className = actionData.getClassName();
        String orderBy = actionData.getOrderBy();
        boolean needRootFlag = actionData.isNeedRootFlag();
        String hierValueCondition = actionData.getHierValueCondition();
        if (StrUtil.isNotBlank(hierValueCondition)) {
            hierValueCondition = hierValueCondition.replace("'$", "insValues->'$");
            condition += " and " + hierValueCondition;
        }
        String model = actionData.getModel();
        Long containerId = actionData.getInstanceId();
        if (StrUtil.equals(model, "staticLogic")) {
            StaticLogicInstance staticLogicInstance = staticLogicInstanceDslService.fetchByClassName(className);
            containerId = staticLogicInstance.getId();
        }
        String parentId = StrUtil.isNotBlank(actionData.getParentId())? actionData.getParentId() : "root";
        Page hierInstancePage = hierInstanceDslService.pageByContainerId(model, containerId, className, condition, needRootFlag, current, size, orderBy);
        hierInstancePage.setRecords(hierInstanceDslService.convertToJson(hierInstancePage.getRecords()));
        return JsonResult.success(hierInstancePage);
    }
    /**
     * 分页查询，并在外层包含containerId
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> queryByPageWithContainerId(ActionData<JSONObject> actionData) {
        int current = actionData.getPageNumber();
        int size = actionData.getPageSize();
        String condition = actionData.getCondition();
        String className = actionData.getClassName();
        String orderBy = actionData.getOrderBy();
        boolean needRootFlag = actionData.isNeedRootFlag();
        String hierValueCondition = actionData.getHierValueCondition();
        if (StrUtil.isNotBlank(hierValueCondition)) {
            hierValueCondition = hierValueCondition.replace("'$", "insValues->'$");
            condition += " and " + hierValueCondition;
        }
        String model = actionData.getModel();
        Long containerId = actionData.getInstanceId();
        if (StrUtil.equals(model, "staticLogic")) {
            StaticLogicInstance staticLogicInstance = staticLogicInstanceDslService.fetchByClassName(className);
            containerId = staticLogicInstance.getId();
        }
        String parentId = StrUtil.isNotBlank(actionData.getParentId())? actionData.getParentId() : "root";
        Page hierInstancePage = hierInstanceDslService.pageByContainerId(model, containerId, className, condition, needRootFlag, current, size, orderBy);
        hierInstancePage.setRecords(hierInstanceDslService.convertToJson(hierInstancePage.getRecords()));
        JSONObject result = new JSONObject();
        result.put("pageInfo", hierInstancePage);
        result.put("containerId", containerId);
        return JsonResult.success(result);
    }

    /**
     * 查询hier中link的信息
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<?> queryWithLink(ActionData<JSONObject> actionData) {
        List<JSONObject> resultList = new ArrayList<>();
        String condition = actionData.getCondition();
        String hierValueCondition = actionData.getHierValueCondition();
        if (StrUtil.isNotBlank(hierValueCondition)) {
            hierValueCondition = hierValueCondition.replace("'$", "insValues->'$");
            condition += " and " + hierValueCondition;
        }
        String model = actionData.getModel();
        Long containerId = actionData.getInstanceId();
        String className = actionData.getClassName();
        String linkModel = actionData.getLinkModel();
        String linkClassName = actionData.getLinkClassName();
        String linkType = actionData.getLinkType();
        String linkCondition = actionData.getLinkCondition();
        String parentId = StrUtil.isNotBlank(actionData.getParentId())? actionData.getParentId() : "root";
        List<HierInstance> hierInstanceList = hierInstanceDslService.queryChildByContainerId(model, className, containerId, parentId, condition);
        List<HierInstance> newHierInstanceList = hierInstanceList;
        if (StrUtil.isNotBlank(linkModel) || StrUtil.isNotBlank(linkClassName) || StrUtil.isNotBlank(linkType)) {
            newHierInstanceList = hierInstanceDslService.filterNodeList(hierInstanceList, (HierInstance hierInstance) ->
                    StrUtil.isNotBlank(hierInstance.getLinkModel()) && hierInstance.getLinkModel().equals(linkModel) &&
                            StrUtil.isNotBlank(hierInstance.getLinkClassName()) && hierInstance.getLinkClassName().equals(linkClassName) &&
                            StrUtil.isNotBlank(hierInstance.getLinkType()) && hierInstance.getLinkType().equals(linkType));
        }

        for (int i = 0; i < newHierInstanceList.size(); i++) {
            JSONObject resultJson = new JSONObject();
            HierInstance hierInstance = newHierInstanceList.get(i);
            if (hierInstance.getLinkId() == null) {
                continue;
            }
            //
            String newLinkCondition = StrUtil.isNotBlank(linkCondition)? linkCondition + " && id = " + hierInstance.getLinkId() : "  id = " + hierInstance.getLinkId();
            List<JSONObject> tempLinkInstanceList = fetchInstanceList(linkModel, linkClassName, newLinkCondition);
            Optional<JSONObject> valuesOption = tempLinkInstanceList.stream().map(d -> d.getJSONObject("values")).findFirst();
            resultJson.put("linkValues",  valuesOption.orElse(new JSONObject()));
            if (valuesOption.isPresent()) {
                resultJson.put("id", hierInstance.getId());
                resultJson.put("linkId", hierInstance.getLinkId());
                resultJson.put("nodeId", hierInstance.getNodeId());
                resultJson.put("parentId", hierInstance.getParentId());
                resultJson.put("values", hierInstance.getValues());
                resultList.add(resultJson);
            }
        }
        return JsonResult.success(resultList);
    }

    /**
     * 从各个模型中获取数据
     * @param linkModel
     * @param linkClassName
     * @param newLinkCondition
     * @return
     */
    private List<JSONObject> fetchInstanceList(String linkModel, String linkClassName, String newLinkCondition) {
        List<JSONObject> tempLinkInstanceList = new ArrayList<>();
        switch (linkModel) {
            case "staticLogic":
                tempLinkInstanceList = staticLogicInstanceDslService.query(newLinkCondition, linkClassName, null);
                break;
            case "logic":
                tempLinkInstanceList = logicInstanceDslService.query(newLinkCondition, linkClassName, null);
                break;
            case "twins":
                tempLinkInstanceList = twinsInstanceDslService.query(newLinkCondition, linkClassName, null);
                break;
            case "tank":
                tempLinkInstanceList = tankInstanceDslService.query(newLinkCondition, linkClassName, null);
                break;
            case "consume":
                tempLinkInstanceList = consumeInstanceDslService.query(newLinkCondition, linkClassName, null);
                break;
            case "resource":
                tempLinkInstanceList = resourceInstanceDslService.query(newLinkCondition, linkClassName, null);
                break;
        }
        return tempLinkInstanceList;
    }

    /**
     * 处理公式数据
     * @param source
     * @param sourceKey
     * @return
     */
    private Object handleExpression(JSONObject source, String sourceKey) {
        String originSourceKey = sourceKey;
        String[] expressionArray =  ExpressionUtil.handleExpression(sourceKey);
        Object tempValue;
        for (int i = 0; i < expressionArray.length; i++) {
            String expression = expressionArray[i];
            tempValue = JsonUtil.get(source, expression);
            tempValue = tempValue == null ? 0:tempValue;
            sourceKey = sourceKey.replace(expressionArray[i], String.valueOf(tempValue));
            sourceKey = sourceKey.replace("${","");
            sourceKey = sourceKey.replace("}","");
        }
        if (originSourceKey.contains("${")) {
            return AviatorEvaluator.execute(sourceKey);
        } else {
            return sourceKey;
        }
    }

    /**
     * 按条件更新
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> updateByCondition(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        String containerModel = actionData.getModel();
        String className = actionData.getClassName();
        String condition = actionData.getCondition();
        JSONObject dataJson = JsonUtil.toJSONObject(data.get(0));
        List<HierInstance> hierInstanceList = hierInstanceDslService.query(containerModel, className, condition);
        JSONObject values = dataJson.getJSONObject("values");
        hierInstanceList.forEach(d->d.setValues(JsonUtil.merge(d.getValues(), values)));
        hierInstanceDslService.updateBatchById(hierInstanceList);
        return JsonResult.success();
    }

    /**
     * 按条件更新，第个data都有自己是否更新的条件
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> updateByDataCondition(ActionData<JSONObject> actionData) {
        String containerModel = actionData.getModel();
        String className = actionData.getClassName();
        String exceptionMsg = actionData.getExceptionMsg();
        List<JSONObject> dataList = actionData.getData();
        dataList.forEach(data->{
            String exceptionKey = data.getString("exceptionKey");
            String condition = data.getString("condition");
            List<HierInstance> hierInstanceList = hierInstanceDslService.query(containerModel, className, condition);
            if (CollectionUtil.isEmpty(hierInstanceList) && StrUtil.isNotBlank(exceptionKey)) {
                throw new BusinessException(StatusCode.ERROR_DATA_ERROR.getCode(), exceptionMsg.replace("{}", exceptionKey));
            }
            JSONObject paramValues = data.getJSONObject("values");
            hierInstanceList.forEach(hierInstance->{
                String newParamValueStr = JsonUtil.handleCondition(JSON.toJSONString(paramValues), hierInstance.getValues());
                JSONObject newParamValueJson = JSON.parseObject(newParamValueStr);
                newParamValueJson.forEach((k,v)->{
                    if (StrUtil.containsAnyIgnoreCase(String.valueOf(v), "+", "-", "*", "/")) {
                        v = AviatorEvaluator.execute(String.valueOf(v));
                        newParamValueJson.put(k, v);
                    }
                });

                hierInstance.setValues(JsonUtil.merge(hierInstance.getValues(), newParamValueJson));
            });
            log.info("update Count = {}", hierInstanceList.size());
            hierInstanceDslService.updateBatchById(hierInstanceList);
        });
        return JsonResult.success();
    }

    //endregion

}
